package com.rm.zeyou.util.uploadUtil;

import com.alibaba.fastjson.JSON;
import com.aliyun.oss.*;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.UploadFileRequest;
import com.aliyun.oss.model.UploadFileResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;

/**
 * 阿里云 断点续传
 */
@Slf4j
@Component
public class OSSPartsUtil {

    private static String endpoint = "oss-cn-hongkong.aliyuncs.com";//地域节点

    private static String accessKeyId = "LTAI5tGtmTK4tDAYwvwkQqpH";//id

    private static String accessKeySecret = "4Isoj4qexQo9qw5jciVqOQI9LdIdus";//秘钥

    private static String bucketName = "iessqx";//项目名称
    private static String objectName = "image/";//项目名称
    private static String url = "https://iessqx.oss-cn-hongkong.aliyuncs.com/";//项目名称


    public String uploadFile(MultipartFile file) throws ClientException {

        // Endpoint以华东1（杭州）为例，其它Region请按实际情况填写。
        //String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // 从环境变量中获取访问凭证。运行本代码示例之前，请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        //EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        ClientBuilderConfiguration conf = new ClientBuilderConfiguration();
        conf.setIdleConnectionTime(1000*60);
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret, conf);
        File localFilePath = null;
        String objectUrl = null;
        try {
            localFilePath = getLocalFilePath(file);
            String filename = file.getOriginalFilename();

            objectUrl = objectName + filename;
            ObjectMetadata meta = new ObjectMetadata();
            // 指定上传的内容类型。
            //meta.setContentType("video/mp4");

            // 文件上传时设置访问权限ACL。
            // meta.setObjectAcl(CannedAccessControlList.Private);

            // 通过UploadFileRequest设置多个参数。
            // 依次填写Bucket名称（例如examplebucket）以及Object完整路径（例如exampledir/exampleobject.txt），Object完整路径中不能包含Bucket名称。
            UploadFileRequest uploadFileRequest = new UploadFileRequest(bucketName, objectName + filename);
            //log.info("路径:{}", parentPath + "/" + file.getOriginalFilename());
            // 通过UploadFileRequest设置单个参数。
            // 填写本地文件的完整路径，例如D:\\localpath\\examplefile.txt。如果未指定本地路径，则默认从示例程序所属项目对应本地路径中上传文件。
            uploadFileRequest.setUploadFile(localFilePath.getAbsolutePath());
            // 指定上传并发线程数，默认值为1。
            uploadFileRequest.setTaskNum(5);

            // 指定上传的分片大小，单位为字节，取值范围为100 KB~5 GB。默认值为100 KB。
            uploadFileRequest.setPartSize(1 * 1024 * 1024);
            // 开启断点续传，默认关闭。
            uploadFileRequest.setEnableCheckpoint(true);
            // 记录本地分片上传结果的文件。上传过程中的进度信息会保存在该文件中，如果某一分片上传失败，再次上传时会根据文件中记录的点继续上传。上传完成后，该文件会被删除。
            // 如果未设置该值，默认与待上传的本地文件同路径，名称为${uploadFile}.ucp。
            uploadFileRequest.setCheckpointFile(objectName);
            // 文件的元数据。
            uploadFileRequest.setObjectMetadata(meta);
            // 设置上传回调，参数为Callback类型。
            //uploadFileRequest.setCallback("yourCallbackEvent");

            // 断点续传上传。
            UploadFileResult uploadFileResult = ossClient.uploadFile(uploadFileRequest);
            String url = uploadFileResult.getMultipartUploadResult().getLocation();
            log.info("上传完成:{}", JSON.toJSONString(uploadFileResult, true));
            log.info("上传之后的返回的路径:{}", uploadFileResult.getMultipartUploadResult().getLocation());
            return url;
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (Throwable ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            // 关闭OSSClient。
            if (ossClient != null) {
                ossClient.shutdown();
            }
            //删除本地数据
            assert localFilePath != null;
            localFilePath.delete();
        }
        //String fileUrl = url + objectUrl;
        //log.info("上传之后的文件路径:{}", fileUrl);

        return "";
    }

    public static File getLocalFilePath(MultipartFile file) {
        // 将MultipartFile转换为File类型
        //File localFile = new File("D:"+File.separator+"image"+File.separator + file.getOriginalFilename());
        File localFile = new File("/iess/path/video/" + file.getOriginalFilename());

        try {
            // 确保保存目录存在
            if (!localFile.getParentFile().exists()) {
                if (!localFile.getParentFile().mkdirs()) {
                    log.error("Failed to create directories for file saving.");
                    //return "Failed to create directories for file saving.";
                }
            }
            // 将MultipartFile保存到本地
            file.transferTo(localFile);
            log.info("文件地址:{}", localFile.getAbsolutePath());
            // 获取本地路径
            return localFile;
        } catch (IOException e) {
            e.printStackTrace();
            return localFile;
        }
    }
}           